﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Objects;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Data.Entity;

namespace MvcMusicStore.Controllers
{
    [Authorize]
    public class CartController : Controller
    {
        private readonly MusicShopDBEntities db = new MusicShopDBEntities();

        public ActionResult Index()
        {
            return HttpNotFound();
        }

        [HttpGet]
        public ActionResult PurchaseSong([Bind(Prefix = "id")]int? songId)
        {
            if (!songId.HasValue) return HttpNotFound();

            Song song = db.Song.Where(w => w.id == songId.Value)
                              .Include(i => i.Album)
                              .Include(i => i.Author)
                              .Include(i => i.Genre)
                              .Single(s => s.id == songId.Value);

            if (null == song) return HttpNotFound();

            return View(song); // ask Y/N
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [ActionName("PurchaseSong")]
        public ActionResult PurchaseSongValidated([Bind(Prefix = "id")]int? songId)
        {
            if (!songId.HasValue) return HttpNotFound();

            var isPurchasedSong = (from u in db.aspnet_Users
                                   where u.UserName == User.Identity.Name
                                   from s in u.Song
                                   where s.id == songId.Value
                                   select s.id).Any();

            if (isPurchasedSong)
            {
                //return Content("Purchased before");
                return RedirectToAction("SongPurchasedBefore", new { id = songId.Value });
            }

            try
            {
                var user = db.aspnet_Users.Single(c => c.UserName == User.Identity.Name);
                var song = db.Song.Single(c => c.id == songId.Value);
                user.Song.Add(song);

                //db.Attach(user);
                //db.ObjectStateManager.ChangeObjectState(user, EntityState.Modified);
                db.SaveChanges();
            }
            catch
            {
                return Content("Purchasing blocked :("); // FIXME!!! Redirect back
            }
            bool saved = false;
            while (!saved)
            {
                try
                {
                    int? counterBought = db.Song.Single(s => s.id == songId.Value).counterBought;
                    if (counterBought.HasValue)
                    {
                        db.Song.Single(s => s.id == songId.Value).counterBought = counterBought.Value + 1;
                    }
                    else
                    {
                        db.Song.Single(s => s.id == songId.Value).counterBought = 1;
                    }
                    db.SaveChanges();
                    saved = true;
                }
                catch (OptimisticConcurrencyException ex)
                {
                    db.Refresh(RefreshMode.StoreWins, db.Song.Single(s => s.id == songId.Value));
                }
            }


            //return Content("Purchased successfully");
            return RedirectToAction("SongPurchasedSuccessfully", new { id = songId.Value });
        }

        [HttpGet]
        public ActionResult PurchaseAlbum([Bind(Prefix = "id")]int? albumId)
        {
            if (!albumId.HasValue) return HttpNotFound();

            Album album = db.Album.Where(w => w.id == albumId.Value)
                              .Include(i => i.Song)
                              .Include(i => i.Author)
                              .Include(i => i.Genre)
                              .Single(s => s.id == albumId.Value);

            if (null == album) return HttpNotFound();

            return View(album); // ask Y/N
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [ActionName("PurchaseAlbum")]
        public ActionResult PurchaseAlbumValidated([Bind(Prefix = "id")]int? albumId)
        {
            if (!albumId.HasValue) return HttpNotFound();

            var isPurchasedAlbum = (from u in db.aspnet_Users
                                    where u.UserName == User.Identity.Name
                                    from a in u.Album
                                    where a.id == albumId.Value
                                    select a.id).Any();

            if (isPurchasedAlbum)
            {
                //return Content("Purchased before");
                return RedirectToAction("AlbumPurchasedBefore", new { id = albumId.Value });
            }

            try
            {
                var user = db.aspnet_Users.Single(c => c.UserName == User.Identity.Name);
                var album = db.Album.Single(c => c.id == albumId.Value);

                user.Album.Add(album);
                db.SaveChanges();
            }
            catch
            {
                return Content("Purchasing blocked :(");
            }
            bool saved = false;
            while (!saved)
            {
                try
                {
                    int? counterBought = db.Album.Single(s => s.id == albumId.Value).counterBought;
                    if (counterBought.HasValue)
                    {
                        db.Album.Single(s => s.id == albumId.Value).counterBought = counterBought.Value + 1;
                    }
                    else
                    {
                        db.Album.Single(s => s.id == albumId.Value).counterBought = 1;
                    }
                    db.SaveChanges();
                    saved = true;
                }
                catch (OptimisticConcurrencyException ex)
                {
                    db.Refresh(RefreshMode.StoreWins, db.Album.Single(s => s.id == albumId.Value));
                }
            }


            //return Content("Purchased successfully");
            return RedirectToAction("AlbumPurchasedSuccessfully", new { id = albumId.Value });
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }

        public ActionResult SongPurchasedBefore(int id)
        {
            var song = db.Song.Include("Album").Include("Author").Include("Genre").Single(a => a.id == id);
            return View(song);
        }

        public ActionResult AlbumPurchasedBefore(int id)
        {
            var album = db.Album.Include("Song").Include("Author").Include("Genre").Single(a => a.id == id);
            return View(album);
        }

        public ActionResult SongPurchasedSuccessfully(int id)
        {
            var song = db.Song.Include("Album").Include("Author").Include("Genre").Single(a => a.id == id);
            return View(song);
        }

        public ActionResult AlbumPurchasedSuccessfully(int id)
        {
            var album = db.Album.Include("Song").Include("Author").Include("Genre").Single(a => a.id == id);
            return View(album);
        }
    }
}
